package com.smart.five.ioc.dynamic.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * 动态添加bean
 *
 * @author junrui.wang
 * @create 2018/7/2
 */
/*
    需要实现在Spring启动阶段动态注入自定义bean，保证注入的bean也能被aop所增强，
    需要实现bean工厂后置处理器接口BeanFactoryPostProcessor。
 */
@Component
public class UserServiceBeanFactory implements BeanFactoryPostProcessor {
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //将BeanFactoryPostProcessor转化为DefaultListableBeanFactory
        DefaultListableBeanFactory dbc = (DefaultListableBeanFactory) beanFactory;

        //通过BeanDefinitionBuilder创建bean定义
        BeanDefinitionBuilder beanDefinitionBuilder =
                BeanDefinitionBuilder.genericBeanDefinition(UserService.class);

        //设置属性userDao，此属性引用已经定义的bean：userDao
        beanDefinitionBuilder.addPropertyReference("userDao", "userDao");
        //beanDefinitionBuilder.addPropertyReference("loginDao", "loginDao");

        //注册bean定义
        //1.通过registerBeanDefinition注册类定义
        dbc.registerBeanDefinition("userService1",
                beanDefinitionBuilder.getRawBeanDefinition());

        //2.通过registerSingleton直接注入bean定义
        dbc.registerSingleton("userService2", new UserService());
    }
}
